import { type RedisCommandArgument } from '@redis/client/dist/lib/commands'
import { createClient, type RedisClientType } from 'redis'
import logger from './logger'

let client: RedisClientType

/** 初始化Redis客户端 */
export const redisClient = async () => {
  if (client) return client // 如果客户端已经初始化，则不再重复初始化
  client = createClient({
    socket: {
      port: 6379,
    },
  })
  client.on('error', (err) => {
    logger.error('Redis连接失败', err)
  })
  await client.connect()
  return client
}

/**
 * 存入数组或对象 并可选的设置过期时间
 * @param {string} key 键名
 * @param {any} value 要存储的值
 * @param {number | null} ttl 可选，以秒为单位的过期时间，默认不设置
 */
export const setKey = async (key: string, value: any, ttl: number | null = null) => {
  if (!client) await redisClient()
  await client.set(key, JSON.stringify(value))
  if (ttl) {
    await client.expire(key, ttl)
  }
}

/**
 * 读取数组或对象
 * @param {string} key 键名
 * @returns 解析后的JSON对象或数组
 */
export const getKey = async (key: string) => {
  if (!client) await redisClient()
  const value = await client.get(key)
  return value ? JSON.parse(value) : null
}

/**
 * 清除缓存数据
 * @param {string} key 键名
 */
export const delKey = async (key: string) => {
  if (!client) await redisClient()
  await client.del(key)
}

/**
 * 获取匹配模式的所有键名
 * @param {string} pattern 匹配模式
 */
export const getKeyByPattern = async (pattern: RedisCommandArgument) => {
  if (!client) await redisClient()
  return await client.keys(pattern)
}

/**
 * 清空所有缓存数据
 */
export const flushAll = async () => {
  if (!client) await redisClient()
  await client.flushAll()
}
